import DeviceStatus from '@MODEL/DeviceStatus'
import BluUtils from '@UTILS/BluUtils'
import { DeviceStatusFlags } from '@TYPES/BleTypes'

const DEVICE_STATUS_TOKENS_SIZE = 9
class DeviceStatusParser {
  private static toDeviceStatusFlags(flags: number): DeviceStatusFlags {
    const isReportAvailable = !(flags & 0x01) // bitwise and with 0000 0001
    const isFlashLogAvailable = !!(flags & 0x02) // bitwise and with 0000 0010
    const isCommandResponseStatusAvailable = !!(flags & 0x04) // bitwise and with 0000 0100
    const isLastTreatmentStatisticsAvailable = !!(flags & 0x08) // bitwise and with 0001 0000
    const isInNoLoadState = !!(flags & 0x20)// bitwise and with 0010 0000
    const isDevicePaired = !(flags & 0x40) // bitwise and with 0100 0000
    const isDeviceAuthenticated = !(flags & 0x80) // bitwise and with 1000 0000
    console.log('tokenstokenstoDeviceStatusFlags', isReportAvailable, flags)

    return {
      isReportAvailable,
      isFlashLogAvailable,
      isCommandResponseStatusAvailable,
      isLastTreatmentStatisticsAvailable,
      isInNoLoadState,
      isDevicePaired,
      isDeviceAuthenticated,
    } as DeviceStatusFlags
  }

  private static parseTokens = (tokens: Array<string>): DeviceStatus => {
    console.log('tokenstokens', tokens)
    const state = BluUtils.toDeviceState(parseInt(tokens[0], 16))
    const treatmentElapsedTimeInSeconds = parseInt(tokens[1], 16)
    const treatmentTimeLeftInSeconds = parseInt(tokens[2], 16)
    const flags = this.toDeviceStatusFlags(parseInt(tokens[3], 16))
    const treatmentActualIntensityInPercentage = parseInt(tokens[4], 16)
    const treatmentConfiguredIntensityInPercentage = parseInt(tokens[5], 16)
    const pauseRemainingTimeInSeconds = parseInt(tokens[6], 16)
    const numberOfTreatments = parseInt(tokens[7], 10)
    const numberOfPauseTreatmentsLeft = parseInt(tokens[8], 16)
    return new DeviceStatus({
      state,
      flags,
      treatmentElapsedTimeInSeconds,
      treatmentTimeLeftInSeconds,
      treatmentActualIntensityInPercentage,
      treatmentConfiguredIntensityInPercentage,
      pauseRemainingTimeInSeconds,
      numberOfTreatments,
      numberOfPauseTreatmentsLeft,
    })
  }

  static parse(data?: string | null) {
    const trimmedString = data?.substr(0, data?.lastIndexOf(String.fromCharCode(0)))
    const tokens = trimmedString?.split(' ')
    if (!tokens || tokens.length !== DEVICE_STATUS_TOKENS_SIZE) {
      console.log('DeviceStatusParser: Parse device status - wrong number of tokens')
      return new DeviceStatus()
    }
    const status = this.parseTokens(tokens)
    console.log('DeviceStatusParser: Parse device status', status)
    return status
  }
}

export default DeviceStatusParser
